#include <panel.h>
#include "tile.h"
#include "level.h"
#include "actor.h"
#include "game.h"
#include "item.h"
#include "buffer.h"
#include "extras.h"

extern WINDOW* mapwin;
extern PANEL* mappan;
extern Actor Player;
extern Tile LoadedTile[NUM_TILES];
extern Item LoadedItem[NUM_ITEMS];
extern Level Map;
extern GameInfo Game;
extern Buffer Buff;

Tile::Tile(Tile& in,int r,int c) : walkable(in.walkable),opaque(in.opaque),seen(false),lit(0),toggles(in.toggles),
		toggles_into(in.toggles_into),inv(NULL){
	id=in.id;
	name=in.name;
	a_name=in.a_name;
	the_name=in.the_name;
	symbol=in.symbol;
	color=in.color;
	row=r;
	col=c;
}
void Tile::CloneSelf(int r,int c){
	Tile* temp = new Tile(*this,r,c);
	Map.SetTilePtr(temp,r,c);
}
void Tile::Define(int id_,string name_,char symbol_,int color_,bool walkable_,bool opaque_,bool toggles_,int toggles_into_){
	id=id_;
	name=name_;
	the_name="the " + name;
	char* sub = (char *)name.c_str();
	switch(sub[0]){
		case 'a':
		case 'e':
		case 'i':
		case 'o':
		case 'u':
		case 'A':
		case 'E':
		case 'I':
		case 'O':
		case 'U':
			a_name = "an " + name;
			break;
		default:
			a_name = "a " + name;
			break;
	}
	symbol=symbol_;
	color=color_;
	walkable=walkable_;
	opaque=opaque_;
	toggles=toggles_;
	toggles_into=toggles_into_;
}
void Tile::Define(Tile& in){
	id=in.id;
	name=in.name;
	the_name=in.the_name;
	a_name=in.a_name;
	symbol=in.symbol;
	color=in.color;
	walkable=in.walkable;
	opaque=in.opaque;
	toggles=in.toggles;
	toggles_into=in.toggles_into;
}
void Tile::RFG(){
	if(inv!=NULL){
		delete inv;
	}
	Map.DelTilePtr(row,col);
	delete this;
}
void Tile::Draw(bool visible,bool draw_lit){
	seen=true;
	chtype p=symbol;
	if(symbol=='#'){
		p=ACS_CKBOARD;
	}
	if(visible){
		if(Map.ActorPtr(row,col)!=NULL){
			Map.ActorPtr(row,col)->Draw();
		}
		else{
			if(inv!=NULL){
				inv->Draw();
			}
			else{
				if(draw_lit){
					wmove(mapwin,row,col);
					wattron(mapwin,A_BOLD);
					wattron(mapwin,COLOR_PAIR(COLOR_YELLOW));
					waddch(mapwin,p);
					wattroff(mapwin,COLOR_PAIR(COLOR_YELLOW));
					wattroff(mapwin,A_BOLD);
				}
				else{
					if(ID()==6){
						wmove(mapwin,row,col);
						if(color > 7){
							wattron(mapwin,A_BOLD);
							wattron(mapwin,COLOR_PAIR(color-8));
						}
						else{
							wattron(mapwin,COLOR_PAIR(color));
						}
						waddch(mapwin,p);
						if(color > 7){
							wattroff(mapwin,A_BOLD);
							wattroff(mapwin,COLOR_PAIR(color-8));
						}
						else{
							wattroff(mapwin,COLOR_PAIR(color));
						}
					}
					else{
						if(ID()==5){
							wmove(mapwin,row,col);
							wattron(mapwin,A_BOLD);
							wattron(mapwin,COLOR_PAIR(GREEN));
							waddch(mapwin,p);
							wattroff(mapwin,COLOR_PAIR(GREEN));
							wattroff(mapwin,A_BOLD);
						}
						else{
							wmove(mapwin,row,col);
							wattron(mapwin,COLOR_PAIR(COLOR_CYAN));
							waddch(mapwin,p);
							wattroff(mapwin,COLOR_PAIR(COLOR_CYAN));
						}
					}
				}
			}
		}
	}
	else{
		if(inv!=NULL){
			inv->Draw();
		}
		else{
			wmove(mapwin,row,col);
			if(color > 7){
				wattron(mapwin,A_BOLD);
				wattron(mapwin,COLOR_PAIR(color-8));
			}
			else{
				wattron(mapwin,COLOR_PAIR(color));
			}
			waddch(mapwin,p);
			if(color > 7){
				wattroff(mapwin,A_BOLD);
				wattroff(mapwin,COLOR_PAIR(color-8));
			}
			else{
				wattroff(mapwin,COLOR_PAIR(color));
			}
		}
	}
}
void Tile::PlusLight(){
	if(!opaque){
		++lit;
	}
}
void Tile::MinusLight(){
	if(!opaque){
		--lit;
		if(lit < 0){
			lit=0;
		}
	}
}
void Tile::GetItem(Item* ptr){
	ptr->SetPos(row,col);
	if(inv==NULL){
		inv=ptr;
	}
	else{
		if(Map.TilePtr(row,col-1)->IsWalkable() && Map.TilePtr(row,col-1)->ItemPtr()==NULL){
			Map.TilePtr(row,col-1)->GetItem(ptr);
		}
		else{
			if(Map.TilePtr(row,col+1)->IsWalkable() && Map.TilePtr(row,col+1)->ItemPtr()==NULL){
				Map.TilePtr(row,col+1)->GetItem(ptr);
			}
			else{
				if(Map.TilePtr(row+1,col)->IsWalkable() && Map.TilePtr(row+1,col)->ItemPtr()==NULL){
					Map.TilePtr(row+1,col)->GetItem(ptr);
				}
				else{
					if(Map.TilePtr(row-1,col)->IsWalkable() && Map.TilePtr(row-1,col)->ItemPtr()==NULL){
						Map.TilePtr(row-1,col)->GetItem(ptr);
					}
					else{
						if(Map.TilePtr(row+1,col-1)->IsWalkable() && Map.TilePtr(row+1,col-1)->ItemPtr()==NULL){
							Map.TilePtr(row+1,col-1)->GetItem(ptr);
						}
						else{
							if(Map.TilePtr(row-1,col-1)->IsWalkable() && Map.TilePtr(row-1,col-1)->ItemPtr()==NULL){
								Map.TilePtr(row-1,col-1)->GetItem(ptr);
							}
							else{
								if(Map.TilePtr(row+1,col+1)->IsWalkable() && Map.TilePtr(row+1,col+1)->ItemPtr()==NULL){
									Map.TilePtr(row+1,col+1)->GetItem(ptr);
								}
								else{
									if(Map.TilePtr(row-1,col+1)->IsWalkable() && Map.TilePtr(row-1,col+1)->ItemPtr()==NULL){
										Map.TilePtr(row-1,col+1)->GetItem(ptr);
									}
									else{
										delete ptr;
									}
								}
							}
						}
					}
				}
			}
		}
	}
}
bool Tile::OpaqueIsLit(int y1,int x1){
	int y2 = row;
	int x2 = col;
	int dx = abs(x2-x1);
	int dy = abs(y2-y1);
	if(y1 == y2){
		if(x1 > x2){ //4
			if(Map.TilePtr(y2,x2+1)->IsLit()){
				return true;
			}
		}
		else{ //6
			if(Map.TilePtr(y2,x2-1)->IsLit()){
				return true;
			}
		}
		return false;
	}
	if(x1 == x2){
		if(y1 > y2){ //8
			if(Map.TilePtr(y2+1,x2)->IsLit()){
				return true;
			}
		}
		else{ //2
			if(Map.TilePtr(y2-1,x2)->IsLit()){
				return true;
			}
		}
		return false;
	}
	if(y1 + x1 == y2 + x2){
		if(y1 > y2){ //9
			if(Map.TilePtr(y2+1,x2-1)->IsLit()){
				return true;
			}
		}
		else{ //1
			if(Map.TilePtr(y2-1,x2+1)->IsLit()){
				return true;
			}
		}
		return false;
	}
	if(y1 - x1 == y2 - x2){
		if(y1 > y2){ //7
			if(Map.TilePtr(y2+1,x2+1)->IsLit()){
				return true;
			}
		}
		else{ //3
			if(Map.TilePtr(y2-1,x2-1)->IsLit()){
				return true;
			}
		}
		return false;
	}
	if(y1 > y2){
		if(x1 > x2){
			if(dx > dy){ //between 4 and 7
				if(Map.TilePtr(y2,x2+1)->IsLit()){
					return true;
				}
				if(Map.TilePtr(y2+1,x2+1)->IsLit()){
					return true;
				}
			}
			else{ //between 8 and 7
				if(Map.TilePtr(y2+1,x2)->IsLit()){
					return true;
				}
				if(Map.TilePtr(y2+1,x2+1)->IsLit()){
					return true;
				}
			}
		}
		else{
			if(dx > dy){ //between 6 and 9
				if(Map.TilePtr(y2,x2-1)->IsLit()){
					return true;
				}
				if(Map.TilePtr(y2+1,x2-1)->IsLit()){
					return true;
				}
			}
			else{ //between 8 and 9
				if(Map.TilePtr(y2+1,x2)->IsLit()){
					return true;
				}
				if(Map.TilePtr(y2+1,x2-1)->IsLit()){
					return true;
				}
			}
		}
	}
	else{
		if(x1 > x2){
			if(dx > dy){ //between 4 and 1
				if(Map.TilePtr(y2,x2+1)->IsLit()){
					return true;
				}
				if(Map.TilePtr(y2-1,x2+1)->IsLit()){
					return true;
				}
			}
			else{ //between 2 and 1
				if(Map.TilePtr(y2-1,x2)->IsLit()){
					return true;
				}
				if(Map.TilePtr(y2-1,x2+1)->IsLit()){
					return true;
				}
			}
		}
		else{
			if(dx > dy){ //between 6 and 3
				if(Map.TilePtr(y2,x2-1)->IsLit()){
					return true;
				}
				if(Map.TilePtr(y2-1,x2-1)->IsLit()){
					return true;
				}
			}
			else{ //between 2 and 3
				if(Map.TilePtr(y2-1,x2)->IsLit()){
					return true;
				}
				if(Map.TilePtr(y2-1,x2-1)->IsLit()){
					return true;
				}
			}
		}
	}
	return false;
}

